﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace Walson.Tools
{
    /// <summary>
    /// 转换工具
    /// </summary>
    static public class Convert
    {
        /// <summary>
        /// 结构/类转换为字节数组
        /// </summary>
        /// <param name="structObj">要进行转换的结构或类</param>
        /// <returns>字节数组</returns>
        static public byte[] ToBytes(object structObj)
        {
            int size = Marshal.SizeOf(structObj);
            byte[] bytes = new byte[size];
            IntPtr structPtr = Marshal.AllocHGlobal(size);
            Marshal.StructureToPtr(structObj, structPtr, false);
            Marshal.Copy(structPtr, bytes, 0, size);
            Marshal.FreeHGlobal(structPtr);
            return bytes;
        }

        /// <summary>
        /// 字节数组转换为结构体/类
        /// </summary>
        /// <typeparam name="T">目标类型</typeparam>
        /// <param name="bytes">字节数组</param>
        /// <param name="type">目标类型</param>
        /// <returns>目标结构/类</returns>
        static public T ToStruct<T>(byte[] bytes)
        {
            int size = Marshal.SizeOf(typeof(T));
            if (size > bytes.Length)
                return default(T);

            IntPtr structPtr = Marshal.AllocHGlobal(size);
            Marshal.Copy(bytes, 0, structPtr, Math.Min(size, bytes.Length));
            T obj =(T) Marshal.PtrToStructure(structPtr, typeof(T));
            Marshal.FreeHGlobal(structPtr);
            return obj;
        }
    }

    /// <summary>
    /// 高精度时间跟踪
    /// </summary>
    public class TrackTime
    {
        [DllImport("kernel32.dll")]
        private static extern bool QueryPerformanceFrequency(out long lpm_Frequency);

        [DllImport("kernel32.dll")]
        private static extern bool QueryPerformanceCounter(out long lpPerformanceCount);

        private long m_StartTime, m_StopTime, m_Freq;

        /// <summary>
        /// 高精度时间测量
        /// </summary>
        public TrackTime()
        {
            this.m_StartTime = 0;
            this.m_StopTime = 0;
            if (QueryPerformanceFrequency(out m_Freq) == false)
            {
                throw new Exception();
            }
        }

        /// <summary>
        /// 启动时间测量
        /// </summary>
        public void Start()
        {
            System.Threading.Thread.Sleep(0);
            QueryPerformanceCounter(out m_StartTime);
        }

        /// <summary>
        /// 距开始计时到此刻所经过的时长（毫秒）
        /// </summary>
        public double DurationMS
        {
            get
            {
                QueryPerformanceCounter(out m_StopTime);
                return (double)(m_StopTime - m_StartTime) * 1000.0 / (double)m_Freq;
            }
        }
    }
}
